<?php

namespace App\Models;

use App\Libraries\Tree;
use App\Models\ComModel;

class MenuModel extends ComModel
{

    protected $ids;
    public $tablename;

    public function __construct(...$param)
    {
        parent::__construct(...$param);

    }

    /**
     * 条件查询
     */
    private function _where(&$select, $data)
    {
        if ($data) {
            // 时间搜索
            if (isset($data['name']) && $data['name']) {
                $select->where('name', $data['name']);
            }

            if (isset($data['pid'])) {
                $select->where('pid', $data['pid']);
            }
        }
        return $data;
    }

    /**
     * 数据分页显示
     */
    public function limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {
        ams_clean_xss($param);
        $param['pid'] = 0;
        $page = max(1, (int) $page);
        $total = (int) $total;
        if ($param) {
            $param = esc($param);
        }
        unset($param['page']);
        if ($size > 0 && !$total) {
            $select = $this->db->table('admin_menu')->select('count(*) as total');
            $param = $this->_where($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：admin_menu');
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table('admin_menu');
        $param = $this->_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy('id', 'asc')->get();
        if (!$query) {
            log_message('error', '数据查询失败：admin_menu');
            return [[], $total, $param];
        }
        $data = $query->getResultArray();

        if ($data) {
            foreach ($data as $k => $v) {
                $sons = $this->db->table('admin_menu')->where('pid', $v['id'])->get()->getResultArray();
                if ($sons) {
                    $data = array_merge($data, $sons);
                }
            }
            $tree = new Tree();
            $data = $tree->get($data);
        }
        $param['total'] = $total;
        return [$data, $total, $param];
    }

    // 新增后台菜单
    public function add($table, $pid = 0, $data)
    {
        $pid = intval($pid);
        $table = esc($table);

        if (!$table) {
            return ams_rt(1, '数据库不存在');
        }
        if ($pid) {
            $row = $this->db->table($table . '_menu')->select('id,pid')->where('id', $pid)->get()->getRowArray();
            if (!$row || $row['pid'] > 0) {
                return ams_rt(1, '上级菜单错误');
            }
        } else {
            $pid = 0;
        }

        $data = esc($data);

        if (!$data['name'] && !$data['uri']) {
            return ams_rt(1, '请填写菜单名称 和 URI地址');
        }
        if (isset($data['uri']) && $this->db->table($table . '_menu')->where('uri', $data['uri'])->countAllResults()) {
            return ams_rt(1, '菜单已存在');
        }

        $this->db->table($table . '_menu')->insert([
            'pid' => $pid,
            'name' => $data['name'],
            'uri' => isset($data['uri']) ? $data['uri'] : '',
            'param' => isset($data['param']) ? $data['param'] : '',
            'url' => isset($data['url']) ? $data['url'] : '',
            'icon' => isset($data['icon']) ? $data['icon'] : '',
            'show' => isset($data['show']) ? (int) $data['show'] : 1,
            'mark' => $data['mark'] ?? '',
            'displayorder' => isset($data['displayorder']) ? (int) $data['displayorder'] : 0,
        ]);
        $id = $this->db->insertID();
        if ($id) {
            $this->cacheData();
            return ams_rt(0, '成功', ['id' => $id]);
        }
        return ams_rt(1, '失败');

    }

    // 修改菜单
    public function edit($table, $id, $data)
    {
        $data = esc($data);
        if ($table == 'admin') {
            $this->db->table('admin_menu')->where('id', (int) $id)->update($data);
        } else {
            $this->db->table('user_menu')->where('id', (int) $id)->update($data);
        }
        $this->cacheData();
        return $id;
    }

    // 后台菜单合并
    private function _admin_add_menu($menu, $new)
    {
        foreach ($new as $mk1 => $top) {
            // 合并顶级菜单
            if ($mk1 && isset($menu[$mk1])) {
                // 它存在分组菜单时才合并
                if ($top['left']) {
                    foreach ($top['left'] as $mk2 => $left) {
                        if ($mk2 && isset($menu[$mk1]['left'][$mk2])) {
                            foreach ($left['link'] as $link) {
                                $menu[$mk1]['left'][$mk2]['link'][] = $link;
                            }
                        } else {
                            $menu[$mk1]['left'][] = $left;
                        }
                    }
                }
            } else {
                $menu[$mk1] = $top;
            }
        }
        return $menu;
    }

    // 用户菜单合并
    private function _user_add_menu($menu, $new)
    {

        foreach ($new as $mk1 => $top) {
            // 合并顶级菜单
            if ($mk1 && isset($menu[$mk1])) {
                // 它存在下级菜单时才合并
                if ($top['link']) {
                    foreach ($top['link'] as $left) {
                        $menu[$mk1]['link'][] = $left;
                    }
                }
            } else {
                $menu[$mk1] = $top;
            }
        }

        return $menu;
    }

    // 初始化菜单
    public function init($table = '')
    {

        if (is_file(APPPATH . 'Config/Menu.php')) {
            $menuDefault = require APPPATH . 'Config/Menu.php';
        } else {
            // 框架主菜单
            return ams_rt(1, '菜单配置文件(Menu.php)不存在');
        }

        if ($table == 'admin' || !$table) {
            $menu = $menuDefault['admin'];
            // 清空表
            $this->db->table('admin_menu')->truncate();
            $this->db->table('admin_menu')->emptyTable();
            foreach ($menu as $top) {
                // 插入顶级菜单
                $rt = $this->add('admin', 0, $top);
                if ($rt['code'] == 0) {
                    $top_id = $rt['data']['id'];
                } else {
                    return false;
                }
                // 插入分组菜单
                if ($top_id) {
                    foreach ($top['menu'] as $left) {
                        $this->add('admin', $top_id, $left);
                    }
                }
            }

        } else {
            $menu = $menuDefault['user'];

            // 清空表
            $this->db->table('user_menu')->truncate();
            $this->db->table('user_menu')->emptyTable();
            foreach ($menu as $top) {
                // 插入顶级菜单
                $top_id = $this->add('user', 0, $top);
                // 插入链接菜单
                if ($top_id) {
                    foreach ($top['link'] as $link) {
                        $this->add('user', $top_id, $link);
                    }
                }
            }
        }
        return ams_rt(0, '操作成功');
    }

    // 初始化菜单
    public function init_apps($dirname, $table = '')
    {
        $file = APPSPATH . ucfirst($dirname) . '/Config/Menu.php';
        if (is_file($file)) {
            $menuDefault = require $file;
        } else {
            // 框架主菜单
            return ams_rt(1, 'APP菜单配置文件(Menu.php)不存在');
        }

        $mark = 'app-' . strtolower($dirname);
        if ($table == 'admin' || !$table) {
            $menu = $menuDefault['admin'];
            // 清空表
            // $this->db->table('admin_menu')->truncate();
            // $this->db->table('admin_menu')->emptyTable();

            foreach ($menu as $top) {
                $top['mark'] = $mark;
                // 插入顶级菜单
                $rt = $this->add('admin', 0, $top);
                if ($rt['code'] == 0) {
                    $top_id = $rt['data']['id'];
                } else {
                    return false;
                }
                // 插入分组菜单
                if ($top_id) {
                    foreach ($top['menu'] as $left) {
                        $left['mark'] = $mark;
                        $this->add('admin', $top_id, $left);
                    }
                }
            }

        } else {
            $menu = $menuDefault['user'];

            // 清空表
            // $this->db->table('user_menu')->truncate();
            // $this->db->table('user_menu')->emptyTable();
            foreach ($menu as $top) {
                // 插入顶级菜单
                $top['mark'] = $mark;
                $top_id = $this->add('user', 0, $top);
                // 插入链接菜单
                if ($top_id) {
                    foreach ($top['menu'] as $link) {
                        $link['mark'] = $mark;
                        $this->add('user', $top_id, $link);
                    }
                }
            }
        }
        return ams_rt(0, '操作成功');
    }

    public function del_apps($dirname)
    {
        $dirname = esc($dirname);
        $data1 = $this->db->table('admin_menu')->select('id')->where('mark', 'app-' . strtolower($dirname))->get()->getResultArray();
        if ($data1) {
            foreach ($data1 as $v) {
                $ids[] = $v['id'];
            }
            $this->_delete('admin', $ids);
        }

        $data1 = $this->db->table('user_menu')->select('id')->where('mark', 'app-' . strtolower($dirname))->get()->getResultArray();
        if ($data1) {
            foreach ($data1 as $v) {
                $ids[] = $v['id'];
            }
            $this->_delete('user', $ids);
        }

    }

    public function setdisplayorder($id, $displayorder)
    {
        return $this->displayorder($this->tablename, $id, $displayorder);
    }

    public function switchHidden($id, $value)
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $row = $this->db->table('admin_menu')->select('id,name,show')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        if ($value == 1) {
            $this->db->table('admin_menu')->where('id', $id)->update(['show' => 1]);
        } else {
            $this->db->table('admin_menu')->where('id', $id)->update(['show' => 0]);
        }
        return ams_rt(0, '操作成功', $row);
    }

    // 获取单个
    public function getRowData($table, $id)
    {
        return $this->db->table($table . '_menu')->where('id', $id)->get()->getRowArray();
    }

    // 获取菜单
    public function gets($table)
    {

        $menu = [];
        $data = $this->db->table($table . '_menu')->orderBy('displayorder ASC,id ASC')->get()->getResultArray();

        if ($data) {
            $tree = new Tree();
            $menu = $tree->get($data);
        }
        return $menu;
    }

    // 获取顶级菜单
    public function get_top($table)
    {
        if (!$table) {
            return false;
        }
        $menu = [];
        $data = $this->db->table($table . '_menu')->where('pid', 0)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();

        if ($data) {
            foreach ($data as $t) {
                $menu[$t['id']] = $t;
            }
        }
        return $menu;
    }

    public function _delete($table, $ids)
    {
        if (!$table) {
            $res = ams_rt(1, '参数不全');
        } elseif (!$ids) {
            $res = ams_rt(1, '参数不全');
        } else {
            $this->ids = [];
            foreach ($ids as $id) {
                $this->_get_id($table, (int) $id);
            }
            $this->ids && $this->db->table($table . '_menu')->whereIn('id', $this->ids)->delete();
            $res = ams_rt(0, '操作成功');
        }
        $this->cacheData();
    }

    // 获取自己id和子id
    private function _get_id($table, $id)
    {

        if (!$id) {
            return false;
        }

        $this->ids[$id] = $id; //自己

        $data = $this->db->table($table . '_menu')->where('pid', $id)->get()->getResultArray();

        if (!$data) {
            return false;
        }
        foreach ($data as $t) {
            $this->ids[$t['id']] = $t['id'];
            $this->_get_id($table, (int) $t['id']);
        }
    }

    /**
     * 父级菜单选择
     *
     * @param    intval    $level    级别
     * @param    intval    $id        选中项id
     * @param    intval    $name    select部分
     * @return    string
     */
    public function parent_select($table, $level = 0, $id = null, $name = null)
    {
        $level = intval($level);
        $id = intval($id);
        $select = $name ? $name : '<select class="form-control" name="data[pid]">';

        if ($level) {
            $topdata = $this->db->table($table . '_menu')->select('id,name')->where('pid', $id)->get()->getResultArray();
            foreach ($topdata as $t) {
                $select .= '<option value="' . $t['id'] . '"' . ($id == $t['id'] ? ' selected' : '') . '>' . $t['name'] . '</option>';
            }
        } else {
            //不存在上级
            $select .= '<option value="0">顶级菜单</option>';
        }

        $select .= '</select>';

        return $select;
    }

    // 缓存
    public function cacheData()
    {

        $menu = [
            'admin' => [],
            'user' => [],
        ];

        // admin 菜单
        $data = $this->db->table('admin_menu')->where('show', 1)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
        if ($data && IS_ADMIN) {
            $list = [];
            foreach ($data as $t) {
                if ($t['pid'] == 0) {
                    $list[$t['id']] = $t;
                    foreach ($data as $m) {
                        if ($m['pid'] == $t['id']) {
                            if ($m['uri']) {
                                $m['uri'] = url($m['uri'], $m['param']);
                            }
                            if (!$m['url']) {
                                $m['url'] = $m['uri'];
                            }
                            $list[$t['id']]['left'][$m['id']] = $m;
                        }
                    }
                }
            }
            $menu['admin'] = $list;
        }

        // user 菜单
        $data = $this->db->table('user_menu')->where('show', 1)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
        if ($data) {
            $list = [
                'url' => [],
                'uri' => [],
            ];
            foreach ($data as $t) {
                if ($t['pid'] == 0) {
                    $list['url'][$t['id']] = $t;
                    foreach ($data as $n) {
                        if ($n['pid'] == $t['id']) {
                            $list['url'][$t['id']]['link'][$n['id']] = $n;
                        }
                    }
                }
            }
            $menu['user'] = $list;
        }

        $this->cache->save('menu-admin', $menu['admin'], 604800); //缓存一周
        $this->cache->save('menu-user', $menu['user'], 604800); //缓存一周
        return $menu;
    }
}
